home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utilsys / rss14gmd.lha / RSys_1.4gmd / C / Filetype.c < prev    next >
C/C++ Source or Header  |  1996-05-04  |  8KB  |  409 lines

  1. /*
  2.    ***************************************************************************
  3.    *
  4.    * Datei:
  5.    *      RSysFiletype.c
  6.    *
  7.    * Inhalt:
  8.    *
  9.    *      --- Globale Routinen ---
  10.    *
  11.    *    int filetype ( char *Name );
  12.    *
  13.    *      --- Lokale  Routinen ---
  14.    *
  15.    *    static int IsDirectory ( char *Name );
  16.    *    static UBYTE Local2Upper ( UBYTE c );
  17.    *    static UBYTE StrCmp ( char *a , char *b );
  18.    *
  19.    * Bemerkungen:
  20.    *      Routinen zur Ermittlung des Typs einer Datei.
  21.    *
  22.    * Erstellungsdatum:
  23.    *      07-Jul-93     Rolf Böhme
  24.    *
  25.    * Änderungen:
  26.    *      07-Jul-93     Rolf Böhme        Erstellung
  27.    *
  28.    ***************************************************************************
  29.  */
  30.  
  31. #include "RSys.h"
  32. #include "protos.h"
  33.  
  34.  /*
  35.   * Die Routinen zur Überprüfung von Filetypen wurden komplett aus
  36.   * dem Terminalprogramm TERM von Olaf 'Olsen' Barthel entnommen. Ich
  37.   * habe ein paar Teile modifiziert und die Kommentare beibehalten.
  38.   * Faulheit overwhelmed me...;-)
  39.   */
  40.  
  41.  
  42. /*
  43.  * Local2Upper(UBYTE c):
  44.  *
  45.  * Custom version of toupper, will also handle international characters.
  46.  */
  47.  
  48. static UBYTE
  49. Local2Upper (UBYTE c)
  50. {
  51.   return ((UBYTE) ((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : c));
  52. }
  53.  
  54. /*
  55.  * StrCmp(UBYTE *a,UBYTE *b):
  56.  *
  57.  * Custom version of strcmp, compares ignoring case.
  58.  */
  59.  
  60. static UBYTE
  61. StrCmp (char *a, char *b)
  62. {
  63.   for (; Local2Upper ((UBYTE) * a) == Local2Upper ((UBYTE) * b); a++, b++)
  64.     {
  65.       if (!(*a))
  66.     return (0);
  67.     }
  68.  
  69.   return ((UBYTE) (Local2Upper ((UBYTE) * a) - Local2Upper ((UBYTE) * b)));
  70. }
  71.  
  72. static int
  73. IsDirectory (char *Name)
  74. {
  75.   FILEINFOBLOCK *FileInfo;
  76.   int isdir = FALSE;
  77.  
  78.   DPOS;
  79.  
  80.   if (NOT (exist (Name)))
  81.     return FALSE;
  82.  
  83.   if (FileInfo = (FILEINFOBLOCK *) AllocDosObject (DOS_FIB, TAG_DONE))
  84.     {
  85.       BPTR FileLock;
  86.  
  87.       if (FileLock = Lock ((UBYTE *) Name, ACCESS_READ))
  88.     {
  89.       if (Examine (FileLock, FileInfo))
  90.         isdir = (FileInfo->fib_DirEntryType > 0) ? TRUE : FALSE;
  91.  
  92.       UnLock (FileLock);
  93.     }
  94.  
  95.       FreeDosObject (DOS_FIB, FileInfo);
  96.     }
  97.  
  98.   return isdir;
  99. }
  100.  
  101. int
  102. filetype (char *Name)
  103. {
  104. /* A table of valid ASCII characters (7 bits). */
  105.  
  106.   BYTE ValidTab[256] =
  107.   {
  108.     0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
  109.     0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
  110.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  111.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  112.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  113.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  114.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  115.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  116.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  117.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  118.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  119.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  120.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  121.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  122.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  123.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  124.   };
  125.  
  126. /* A table of clearly invalid ASCII characters (8 bits). */
  127.  
  128.   BYTE InvalidTab[256] =
  129.   {
  130.     1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
  131.     1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
  132.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  133.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  134.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  135.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  136.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  137.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  138.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  139.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
  140.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  141.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  142.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  143.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  144.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  145.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  146.   };
  147.   ULONG *Buffer;
  148.   int Type = TYPE_FILE;
  149.   SHORT i, Len = strlen (Name);
  150.  
  151.   DPOS;
  152. /*
  153.  * Allocate a buffer for the first 400 bytes of the file.
  154.  */
  155.  
  156.   if (IsDirectory (Name))
  157.     return TYPE_DIR;
  158.  
  159.   if (Buffer = (ULONG *) MyAllocVec (400, MEMF_CLEAR, NO_KILL))
  160.     {
  161.       BPTR File, Size;
  162.  
  163.       /* Open the file. */
  164.  
  165.       if (File = Open ((UBYTE *) Name, MODE_OLDFILE))
  166.     {
  167.       /* Read the first 400 bytes. */
  168.  
  169.       if ((Size = Read (File, (char *) Buffer, 400)) >= sizeof (ULONG))
  170.         {
  171.           /* Examine the first longword. */
  172.  
  173.           switch (Buffer[0])
  174.         {
  175.         case 0x03E7:
  176.           Type = TYPE_OBJECT;
  177.           break;
  178.  
  179.         case 0x03F3:
  180.           Type = TYPE_EXECUTABLE;
  181.           break;
  182.  
  183.         case 0x03FA:
  184.           Type = TYPE_LIB;
  185.           break;
  186.  
  187.         case 0xF7593647:
  188.           Type = TYPE_TEXFONT;
  189.           break;
  190.  
  191.         case 0xF7020183:
  192.           Type = TYPE_TEXDVI;
  193.           break;
  194.  
  195.         case 0xF7832020:
  196.           Type = TYPE_GF;
  197.           break;
  198.  
  199.         case 'FLIB':
  200.           Type = TYPE_FLIB;
  201.           break;
  202.  
  203.         case 'FORM':
  204.           switch (Buffer[2])
  205.             {
  206.             case 'ILBM':
  207.               Type = TYPE_ILBM;
  208.               break;
  209.  
  210.             case 'ANIM':
  211.               Type = TYPE_ANIM;
  212.               break;
  213.  
  214.             case '8SVX':
  215.               Type = TYPE_8SVX;
  216.               break;
  217.  
  218.             case 'SMUS':
  219.               Type = TYPE_SMUS;
  220.               break;
  221.  
  222.             case 'FTXT':
  223.               Type = TYPE_FTXT;
  224.               break;
  225.  
  226.             case 'PREF':
  227.               Type = TYPE_PREFS;
  228.               break;
  229.  
  230.             case 'TERM':
  231.               Type = TYPE_TERM;
  232.               break;
  233.             }
  234.  
  235.           break;
  236.  
  237.         case 'IMP!':
  238.           Type = TYPE_IMPLODER;
  239.           break;
  240.  
  241.         case 'PP20':
  242.           Type = TYPE_POWERPACKER;
  243.           break;
  244.  
  245.         case 'DMS!':
  246.           Type = TYPE_DMS;
  247.           break;
  248.  
  249.         case 'Warp':
  250.           Type = TYPE_WARP;
  251.           break;
  252.  
  253.         case 'ZOOM':
  254.           Type = TYPE_ZOOM;
  255.           break;
  256.  
  257.         case 0x504B0304:
  258.           Type = TYPE_ZIP;
  259.           break;
  260.  
  261.         case 'ZOO ':
  262.           Type = TYPE_ZOO;
  263.           break;
  264.  
  265.         case 'GIF8':
  266.           Type = TYPE_GIF;
  267.           break;
  268.  
  269.         default:
  270.           break;
  271.         }
  272.  
  273.           /*
  274.            * No match yet, see if it's an ASCII file.
  275.            */
  276.  
  277.           if (Type == TYPE_FILE)
  278.         {
  279.           UBYTE *CharBuffer = (UBYTE *) Buffer;
  280.           SHORT Count = 0;
  281.  
  282.           for (i = 0; i < Size; i++)
  283.             {
  284.               if (ValidTab[CharBuffer[i]])
  285.             Count++;
  286.               else
  287.             {
  288.               if (InvalidTab[CharBuffer[i]])
  289.                 {
  290.                   Count = 0;
  291.                   break;
  292.                 }
  293.             }
  294.             }
  295.  
  296.           /*
  297.            * If more than 75% of the characters in the first 400 bytes
  298.            * are legal ASCII characters this file is supposed to be a
  299.            * text file.
  300.            */
  301.  
  302.           if (Count > 3 * (Size / 4))
  303.             Type = TYPE_TEXT;
  304.         }
  305.  
  306.           /* Still no match, have another try */
  307.  
  308.           if (Type == TYPE_FILE)
  309.         {
  310.           if ((Buffer[0] & 0xFFFF0000) == 0x1A080000)
  311.             Type = TYPE_ARC;
  312.           else
  313.             {
  314.               if ((Buffer[0] & 0x0000FFFF) == 0x00002D6C && (Buffer[1] & 0xFF00FF00) == 0x68002D00)
  315.             Type = TYPE_LHARC;
  316.               else
  317.             {
  318.               switch (Buffer[0] & 0xFFFF0000)
  319.                 {
  320.                 case 0x434A0000:
  321.                   Type = TYPE_NEWMANX;
  322.                   break;
  323.  
  324.                 case 0x414A0000:
  325.                   Type = TYPE_OLDMANX;
  326.                   break;
  327.  
  328.                 case 0x636A0000:
  329.                   Type = TYPE_NEWMANXLIB;
  330.                   break;
  331.  
  332.                 case 0x616A0000:
  333.                   Type = TYPE_OLDMANXLIB;
  334.                   break;
  335.  
  336.                 case 0xF5000000:
  337.                   Type = TYPE_BASIC;
  338.                   break;
  339.  
  340.                 default:
  341.                   break;
  342.                 }
  343.             }
  344.             }
  345.         }
  346.  
  347.           /*
  348.            * Take a look at the file name suffixes.
  349.            */
  350.           global_type = Type;
  351.  
  352.           switch (Type)
  353.         {
  354.         case TYPE_TEXT:
  355.           for (i = 0;
  356.           i < ((sizeof (TextSuffix)) / (sizeof (RSYS_Suffix))); i++)
  357.             {
  358.               Size = strlen (TextSuffix[i].Name);
  359.  
  360.               if (Len >= Size)
  361.             {
  362.               if (!StrCmp (&Name[Len - Size], TextSuffix[i].Name))
  363.                 {
  364.                   Type = TextSuffix[i].Type;
  365.                   break;
  366.                 }
  367.             }
  368.             }
  369.  
  370.           break;
  371.  
  372.         case TYPE_EXECUTABLE:
  373.           for (i = 0; i < sizeof (ExecutableSuffix) / sizeof (RSYS_Suffix); i++)
  374.             {
  375.               Size = strlen (ExecutableSuffix[i].Name);
  376.  
  377.               if (Len >= Size)
  378.             {
  379.               if (!StrCmp (&Name[Len - Size], ExecutableSuffix[i].Name))
  380.                 {
  381.                   Type = ExecutableSuffix[i].Type;
  382.                   break;
  383.                 }
  384.             }
  385.             }
  386.  
  387.           break;
  388.  
  389.         case TYPE_OBJECT:
  390.           if (Len >= 4)
  391.             if (!StrCmp (&Name[Len - 4], ".LIB"))
  392.               Type = TYPE_LIB;
  393.  
  394.           break;
  395.  
  396.         default:
  397.           break;
  398.         }
  399.         }
  400.  
  401.       Close (File);
  402.     }
  403.  
  404.       MyFreeVec (Buffer);
  405.     }
  406.  
  407.   return Type;
  408. }
  409.